package constant.milk.periodapp.database;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;

public class DbAdapter
{
	private static DbAdapter adapter = new DbAdapter();
	
	private SQLiteDatabase db;
	private DbHelper dbHelper;
	
	private DbAdapter(){};
	
	public static DbAdapter getInstance()
	{
		return adapter;
	}
	
	// DB 열기
    public void openWrite(Context context) throws SQLiteException 
    {
    	if (db != null && isOpen())
		{
			return;
		}
    	
    	dbHelper = new DbHelper(context);
    	
        try {
            db = dbHelper.getWritableDatabase(); // 읽고 쓰기 모드로 Open
        } catch (SQLiteException e) {
        	db = null;
        }
    }

	/**
	 * 테이블을 지운다
	 * @param tableName 테이블 명
	 */
	public void dropTable(final Context context, String tableName) throws Exception
	{
		openWrite(context);
		
		if (db == null)
		{
			throw new Exception();
		}
		
		db.execSQL("drop table "+ tableName);
	}
	
	/**
	 * 데이터를 조회한다.
	 * @param sql 쿼리문
	 */
	public Cursor select(Context context, String sql)
	{
		Cursor c = null;
		openWrite(context);
		
		if (db == null)
		{
			return null;
		}
		
		c = db.rawQuery(sql, null);
		
		return c;
	}
	
	/**
	 * 데이터를 삽입한다.
	 * @param content 데이터를 삽입할 키와 벨류값
	 * @param tableName 테이블 이름
	 */
	public void insert(Context context, HashMap<String, String> content, String tableName) throws Exception
	{
		openWrite(context);
		
		if (db == null)
		{
			throw new Exception();
		}
		
		ContentValues cv = getHashMapToContent(content);
		
		db.insert(tableName, null, cv);
	}
	
	/**
	 * 데이터를 업데이트 한다.
	 * @param tableName 테이블명
	 * @param content 바꿀 키와 값
	 * @param whereClause where 구문 
	 * @param whereArgs where 값들 
	 */
	public void update(final Context context, final HashMap<String, String> content, String tableName, 
			final String whereClause, String [] whereArgs) throws Exception
	{
		openWrite(context);
		
		if (db == null)
		{
			throw new Exception();
		}
		
		ContentValues cv = getHashMapToContent(content);
		
		db.update(tableName, cv, whereClause, whereArgs);
	}
	
	/**
	 * 데이터를 지운다.
	 * @param tableName 테이블명
	 * @param whereClause where 구문
	 * @param whereArgs where 값들 
	 */
	public void delete(final Context context, String tableName, 
			String whereClause, String [] whereArgs) throws Exception
	{
		openWrite(context);
		
		if (db == null)
		{
			throw new Exception();
		}
		
		db.delete(tableName, whereClause, whereArgs);
	}
    
    public void beginTansaction(Context context) throws Exception
	{
    	openWrite(context);
		
		db.beginTransaction();
	}
	
	public void setTransactionSuccessful()
	{
		db.setTransactionSuccessful();
	}
	
	public void endTransaction(Context context) throws Exception
	{
		openWrite(context);
		
		db.endTransaction();
	}
    
    /**
     * 디비 닫기
     */
    public void close() 
    {
    	if (db != null)
		{
			if (db.isOpen())
			{
				db.close();
				db = null;
			}
		}
    }
    
    /**
     * 현재 디비 상태
     * @return
     */
    public boolean isOpen()
	{
		return db.isOpen();
	}
    
    public ContentValues getHashMapToContent(HashMap<String, String> hashMap)
	{
		Iterator<Entry<String, String>> iter = hashMap.entrySet().iterator();
		
		ContentValues cv = new ContentValues();
		
		for (int i = 0; i < hashMap.size(); i++)
		{
			Entry<String, String> entry = iter.next();
			cv.put(entry.getKey(), (String) entry.getValue());
		}
		
		return cv;
	}
    
    /**
     * 테이블을 생성한다.
     * @param context
     */
    public void createTable(Context context)
    {
    	openWrite(context);
    	
    	dbHelper.createTable(db);
    }
    
    /**
     * 테이블의 데이터를 지운다.
     * @param context
     */
    public void deleteTable(Context context) throws Exception
    {
    	openWrite(context);
    	
    	delete(context, TableName.PERIOD_DATE, null, null);
		delete(context, TableName.SEX_DATE, null, null);
		delete(context, TableName.MEMO, null, null);
    }
    
    public String getDbPath(Context context)
    {
    	openWrite(context);
    	
    	return db.getPath();
    }

	public SQLiteDatabase getDb(Context context)
	{
		openWrite(context);
		
		return db;
	}
}
